package com.junxonline.plat.service.attence.impl;

import com.junxonline.common.exception.CommonBizException;
import com.junxonline.common.util.CommonUtils;
import com.junxonline.plat.dao.model.Attence;
import com.junxonline.plat.dao.model.Device;
import com.junxonline.plat.dao.model.Household;
import com.junxonline.plat.dao.model.User;
import com.junxonline.plat.dao.repository.AttenceRepository;
import com.junxonline.plat.dao.repository.HouseholdRepository;
import com.junxonline.plat.dao.vo.*;
import com.junxonline.plat.service.attence.AttenceService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class AttenceServiceImpl implements AttenceService {

    private Logger logger = LogManager.getLogger();

    @Autowired
    private AttenceRepository attenceRepository;

    @Autowired
    private HouseholdRepository householdRepository;

    /**
     * 获取考勤数据
     *
     * @param vo
     * @return
     */
    @Override
    public AttenceVO getAttence(QueryAttenceVO vo) {

        Attence attence = attenceRepository.findByAttenceId(vo.getAttenceId());

        AttenceVO attenceVO = new AttenceVO();
        attenceVO.setAttenceId(attence.getAttenceId());
        attenceVO.setAttenceYearMonth(attence.getAttenceYearMonth());
        attenceVO.setAttenceDays(attence.getAttenceDays());
        attenceVO.setAttenceActualDays(attence.getAttenceActualDays());
        attenceVO.setAttenceLaterDays(attence.getAttenceLaterDays());
        attenceVO.setAttenceOvertimeDays(attence.getAttenceOvertimeDays());
        attenceVO.setAttenceLeaveDays(attence.getAttenceLeaveDays());

        Household household = attence.getPersonnel();
        if (CommonUtils.isNotEmpty(household)) {
            attenceVO.setHouseholdId(household.getHouseholdId());
            attenceVO.setHouseholdName(household.getHouseholdName());
            attenceVO.setHouseholdNo(household.getHouseholdNo());
        }

        return attenceVO;
    }

    /**
     * 筛选查询考勤
     *
     * @param pageVO
     * @param vo
     * @return
     */
    @Override
    public PageVO queryAttence(PageVO pageVO, QueryAttenceVO vo) {

        PageRequest pageRequest = PageRequest.of(pageVO.getPage() - 1, pageVO.getLimit(), new Sort(Sort.Direction.ASC, "attenceId"));

        Page<Attence> page = attenceRepository.findAll(new Specification<Attence>() {
            @Override
            public Predicate toPredicate(Root<Attence> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

                List<Predicate> params = new ArrayList<>();
                String personnelNo = vo.getHouseholdNo();
                String personnelName = vo.getHouseholdName();
                String attenceYearMonth = vo.getAttenceYearMonth();

                Join householdMap = root.join("personnel", JoinType.LEFT);

                params.add(criteriaBuilder.equal(householdMap.get("isWorker"), 1));

                if (CommonUtils.isNotEmpty(personnelNo)) {
                    params.add(criteriaBuilder.like(householdMap.get("householdNo"), "%" + personnelNo + "%"));
                }

                if (CommonUtils.isNotEmpty(personnelName)) {
                    params.add(criteriaBuilder.like(householdMap.get("householdName"), "%" + personnelName + "%"));
                }

                if (CommonUtils.isNotEmpty(attenceYearMonth)) {
                    params.add(criteriaBuilder.like(root.get("attenceYearMonth").as(String.class), "%" + attenceYearMonth + "%"));
                }

                return criteriaBuilder.and(params.toArray(new Predicate[params.size()]));
            }
        }, pageRequest);

        List<AttenceVO> attenceVOs = new ArrayList<>();
        List<Attence> attences = page.getContent();

        for (Attence attence : attences) {

            AttenceVO attenceVO = new AttenceVO();
            attenceVO.setAttenceYearMonth(attence.getAttenceYearMonth());
            attenceVO.setAttenceId(attence.getAttenceId());
            attenceVO.setAttenceLeaveDays(attence.getAttenceLeaveDays());
            attenceVO.setAttenceOvertimeDays(attence.getAttenceOvertimeDays());
            attenceVO.setAttenceLaterDays(attence.getAttenceLaterDays());
            attenceVO.setAttenceActualDays(attence.getAttenceActualDays());
            attenceVO.setAttenceDays(attence.getAttenceDays());

            Household household = attence.getPersonnel();
            if (CommonUtils.isNotEmpty(household)) {
                attenceVO.setHouseholdId(household.getHouseholdId());
                attenceVO.setHouseholdName(household.getHouseholdName());
                attenceVO.setHouseholdNo(household.getHouseholdNo());
            }

            attenceVOs.add(attenceVO);
        }

        pageVO.setTotal(page.getTotalElements());
        pageVO.setData(attenceVOs);

        return pageVO;

    }

    /**
     * 添加考勤
     *
     * @param vo
     * @return
     */
    @Override
    public boolean addAttence(AttenceVO vo) {

        Attence attence = new Attence();
        attence.setAttenceYearMonth(vo.getAttenceYearMonth());
        attence.setAttenceDays(vo.getAttenceDays());
        attence.setAttenceActualDays(vo.getAttenceActualDays());
        attence.setAttenceLaterDays(vo.getAttenceLaterDays());
        attence.setAttenceOvertimeDays(vo.getAttenceOvertimeDays());
        attence.setAttenceLeaveDays(vo.getAttenceLeaveDays());

        Household personnel = householdRepository.findByHouseholdId(vo.getHouseholdId());

        if (CommonUtils.isEmpty(personnel)) {
            throw CommonBizException.SYSTEM_ERROR;
        }

        attence.setPersonnel(personnel);

        attenceRepository.save(attence);

        return true;
    }

    /**
     * 修改考勤
     *
     * @param vo
     * @return
     */
    @Override
    public boolean editAttence(AttenceVO vo) {

        Attence attence = attenceRepository.findByAttenceId(vo.getAttenceId());

        attence.setAttenceYearMonth(vo.getAttenceYearMonth());
        attence.setAttenceDays(vo.getAttenceDays());
        attence.setAttenceActualDays(vo.getAttenceActualDays());
        attence.setAttenceLaterDays(vo.getAttenceLaterDays());
        attence.setAttenceOvertimeDays(vo.getAttenceOvertimeDays());
        attence.setAttenceLeaveDays(vo.getAttenceLeaveDays());

        if (CommonUtils.isNotEmpty(vo.getHouseholdId())) {

            Household household = householdRepository.findByHouseholdId(vo.getHouseholdId());

            if (CommonUtils.isNotEmpty(household)) {
                attence.setPersonnel(household);
            }
        }

        attenceRepository.save(attence);

        return true;
    }

    /**
     * 删除考勤
     *
     * @param attenceIds
     * @return
     */
    @Override
    public boolean delAttence(Long[] attenceIds) {

        List<Attence> attences = attenceRepository.findByAttenceIdIn(attenceIds);

        for (Attence attence : attences) {
            // 删除考勤
            attenceRepository.delete(attence);
        }


        return true;
    }


    /**
     * 获取员工数据
     *
     * @param vo
     * @return
     */
    @Override
    public List<HouseholdVO> getHousehold(QueryHouseholdVO vo) {

        List<HouseholdVO> householdVOList = new ArrayList<>();
        List<Household> households = householdRepository.findByHouseholdNameLikeAndIsWorker(vo.getHouseholdName(), 1);

        for (Household household : households) {

            HouseholdVO householdVO = new HouseholdVO();
            householdVO.setHouseholdId(household.getHouseholdId());
            householdVO.setHouseholdName(household.getHouseholdName());
            householdVO.setHouseholdNo(household.getHouseholdNo());
            householdVOList.add(householdVO);
        }

        return householdVOList;
    }

}
